package ace.module.oauth2.server.core.impl.manager.impl;

import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.manager.spring.AbstractSpringDtoManager;
import ace.module.oauth2.server.api.enums.Oauth2RegisteredClientAuthConfigBizAuthTypeEnum;
import ace.module.oauth2.server.api.enums.Oauth2RegisteredClientAuthConfigStatusEnum;
import ace.module.oauth2.server.api.model.dto.Oauth2RegisteredClientAuthConfigDto;
import ace.module.oauth2.server.core.impl.dao.entity.Oauth2RegisteredClientAuthConfig;
import ace.module.oauth2.server.core.impl.manager.Oauth2RegisteredClientAuthConfigManager;
import ace.module.oauth2.server.core.impl.manager.cache.Oauth2RegisteredClientAuthConfigCacheManager;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * oauth2客户端支持的授权协议配置,支持本地bean与rest授权方式 spring data jdbc querydsl rsql manager implement.
 *
 * @author Caspar
 */
@Slf4j
@AllArgsConstructor
@Component
public class Oauth2RegisteredClientAuthConfigManagerImpl
    extends AbstractSpringDtoManager<Oauth2RegisteredClientAuthConfig, Long, Oauth2RegisteredClientAuthConfigDto>
    implements Oauth2RegisteredClientAuthConfigManager {

  private final Oauth2RegisteredClientAuthConfigCacheManager oauth2RegisteredClientAuthConfigCacheManager;


  @Override
  public List<Oauth2RegisteredClientAuthConfig> getByIdOfClientAndDeleteFlagIsFalseFormDbOrCache(String idOfClient) {
    return oauth2RegisteredClientAuthConfigCacheManager.getByIdOfClientAndDeleteFlagIsFalse(idOfClient);
  }

  @Override
  public List<Oauth2RegisteredClientAuthConfig> getByIdOfClientAndStatusIsEnableAndDeleteFlagIsFalseFormDbOrCache(String idOfClient) {
    return this.oauth2RegisteredClientAuthConfigCacheManager.getByIdOfClientAndDeleteFlagIsFalse(idOfClient)
        .stream()
        .filter(this::isEnableStatus)
        .collect(Collectors.toList());
  }

  @Override
  public List<Oauth2RegisteredClientAuthConfig> getByAuthTypeFromMemory(List<Oauth2RegisteredClientAuthConfig> allOauth2RegisteredClientAuthConfigs, String authType) {
    return Optional.ofNullable(allOauth2RegisteredClientAuthConfigs)
        .stream()
        .flatMap(List::stream)
        .filter(p -> p.getAuthenticationType().equalsIgnoreCase(authType))
        .collect(Collectors.toList());
  }

  @Override
  public List<Oauth2RegisteredClientAuthConfig> getByIdOfClientAndStatusIsEnableAndBizAuthTypeIsAuthorizationTypeFromDbOrCache(String idOfClient) {
    List<Oauth2RegisteredClientAuthConfig> result = this.oauth2RegisteredClientAuthConfigCacheManager.getByIdOfClientAndDeleteFlagIsFalse(idOfClient)
        .stream()
        .filter(this::isAuthorizationType)
        .filter(this::isEnableStatus)
        .collect(Collectors.toList());

    return result;
  }

  @Override
  public List<Oauth2RegisteredClientAuthConfig> getByIdOfClientAndStatusIsEnableAndBizAuthTypeIsAuthenticationTypeFromDbOrCache(String idOfClient) {
    List<Oauth2RegisteredClientAuthConfig> result = this.oauth2RegisteredClientAuthConfigCacheManager.getByIdOfClientAndDeleteFlagIsFalse(idOfClient)
        .stream()
        .filter(this::isAuthenticationType)
        .filter(this::isEnableStatus)
        .collect(Collectors.toList());

    return result;
  }

  @Override
  public boolean isEnableStatus(Oauth2RegisteredClientAuthConfig oauth2RegisteredClientAuthConfig) {
    return Oauth2RegisteredClientAuthConfigStatusEnum.ENABLE.getCode().equals(oauth2RegisteredClientAuthConfig.getStatus());
  }

  @Override
  public boolean isAuthorizationType(Oauth2RegisteredClientAuthConfig oauth2RegisteredClientAuthConfig) {
    return Oauth2RegisteredClientAuthConfigBizAuthTypeEnum.AUTHORIZATION.getCode().equals(oauth2RegisteredClientAuthConfig.getBizAuthType());
  }

  @Override
  public boolean isAuthenticationType(Oauth2RegisteredClientAuthConfig oauth2RegisteredClientAuthConfig) {
    return Oauth2RegisteredClientAuthConfigBizAuthTypeEnum.AUTHENTICATION.getCode().equals(oauth2RegisteredClientAuthConfig.getBizAuthType());
  }
}
